package com.nb.ds.datasource;

import org.springframework.core.io.Resource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;
import java.util.*;

/**
 * @author lihaoyang6
 * @date 2024年04月22日 15:27
 */
@Configuration
public class DataSourceConfig {

    @Bean
    @ConfigurationProperties("spring.datasource.druid.ds1")
    public DataSource dataSource1(){
        // 底层会自动拿到spring.datasource中的配置， 创建一个DruidDataSource
        return DruidDataSourceBuilder.create().build();
    }
    @Bean
    @ConfigurationProperties("spring.datasource.druid.ds2")
    public DataSource dataSource2(){
        return DruidDataSourceBuilder.create().build();
    }


    @Bean
    public DynamicDataSource dynamicDataSource(DataSource dataSource1, DataSource dataSource2){
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DsConstant.ds1,dataSource1);
        targetDataSources.put(DsConstant.ds2,dataSource2);
        return new DynamicDataSource(targetDataSources,dataSource1);
    }

    /**
     * 当你自定义SqlSessionFactory Bean时，你需要在自定义的SqlSessionFactory中明确地设置别名包和mapper文件的位置。
     * 否则，application.yml中的配置可能不会生效。
     *当你使用MyBatis的Spring Boot Starter自动配置时，它会根据application.yml中的配置来创建SqlSessionFactory。但当你自定义SqlSessionFactory时，Spring Boot Starter的自动配置就不会生效了，因此，你需要在自定义的SqlSessionFactory中设置这些属性。
     *所以，虽然你在application.yml中配置了别名包和mapper文件的位置，但是你还是需要在自定义的SqlSessionFactory中设置这些属性，以确保它们被正确地使用。
     * @param dataSource
     * @return
     * @throws Exception
     */
    @Bean
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dataSource) throws Exception {
        // 使用我们的动态数据源来构建SqlSessionFactory
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        // 设置别名包
        sessionFactory.setTypeAliasesPackage("com.nb.ds.entity");
        // 设置mapper文件的位置
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sessionFactory.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
        return sessionFactory.getObject();
    }

    @Bean
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    /**
     * 注意：虽然Spring会自动管理事务，但是你还需要确保你的DataSourceTransactionManager已经正确配置了你的AbstractRoutingDataSource。
     * 如果没有正确配置，你可能会遇到无法找到合适的事务管理器的错误。
     * @param routingDataSource
     * @return
     */
    @Bean
    public PlatformTransactionManager transactionManager(AbstractRoutingDataSource routingDataSource) {
        return new DataSourceTransactionManager(routingDataSource);
    }

}
